// ============================================
// TypeScript 接口示例
// ============================================

// 1. 基本接口
interface User {
    name: string;
    age: number;
}

function greet(user: User) {
    return `Hello ${user.name}, you are ${user.age} years old!`;
}

let user1: User = { name: "Alice", age: 25 };
console.log(greet(user1));

// 2. 可选属性
interface SquareConfig {
    color?: string;
    width?: number;
    [propName: string]: any; // 索引签名
}

function createSquare(config: SquareConfig): { color: string; area: number } {
    let newSquare = { color: "white", area: 100 };
    if (config.color) {
        newSquare.color = config.color;
    }
    if (config.width) {
        newSquare.area = config.width * config.width;
    }
    return newSquare;
}

// 3. 只读属性
interface ReadonlyPoint {
    readonly x: number;
    readonly y: number;
}

let point: ReadonlyPoint = { x: 10, y: 20 };
// point.x = 5; // 错误

// 4. 函数类型接口
interface SearchFunc {
    (source: string, subString: string): boolean;
}

let mySearch: SearchFunc = function(source: string, subString: string): boolean {
    let result = source.search(subString);
    return result > -1;
};

// 简化写法
let mySearch2: SearchFunc = (src, sub) => src.search(sub) > -1;

// 5. 可索引的类型
// 字符串索引签名
interface StringArray {
    [index: number]: string;
}

let myArray: StringArray = ["Bob", "Fred"];
let myStr: string = myArray[0];

// 字典模式
interface StringDictionary {
    [index: string]: string | number;
    length: number; // 可以，length是number类型
}

// 6. 类类型接口
interface ClockInterface {
    currentTime: Date;
    setTime(d: Date): void;
}

class Clock implements ClockInterface {
    currentTime: Date = new Date();
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

// 7. 继承接口
interface Shape {
    color: string;
}

interface PenStroke {
    penWidth: number;
}

// 继承单个接口
interface Square extends Shape {
    sideLength: number;
}

// 继承多个接口
interface Rectangle extends Shape, PenStroke {
    width: number;
    height: number;
}

let square = {} as Square;
square.color = "blue";
square.sideLength = 10;

let rectangle = {} as Rectangle;
rectangle.color = "red";
rectangle.penWidth = 5.0;
rectangle.width = 20;
rectangle.height = 10;

// 8. 混合类型
// 一个对象可以同时做为函数和对象使用
interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

function getCounter(): Counter {
    let counter = (function (start: number) { return start.toString(); }) as Counter;
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

// 9. 接口继承类
class Control {
    private state: any;
}

// 接口继承了一个类类型，它会继承类的成员但不包括其实现
interface SelectableControl extends Control {
    select(): void;
}

// Button类继承了Control并实现了SelectableControl
class Button extends Control implements SelectableControl {
    select() { }
}

class TextBox extends Control {
    select() { }
}

// 错误："ImageControl"类型缺少"state"属性
// class ImageControl implements SelectableControl {
//     select() { }
// }

// 10. 泛型接口
interface GenericIdentityFn<T> {
    (arg: T): T;
}

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn<number> = identity;

// 11. 接口合并
interface Document {
    createElement(tagName: any): Element;
}

interface Document {
    createElement(tagName: "div"): HTMLDivElement;
    createElement(tagName: "span"): HTMLSpanElement;
}

interface Document {
    createElement(tagName: string): HTMLElement;
    createElement(tagName: "canvas"): HTMLCanvasElement;
}

// 合并后的Document接口包含所有声明

console.log("=== 接口示例完成 ===");